package lib.random;

import java.util.ArrayList;

/**
 * Creates random forests, which is a collection of trees.
 * @author dolphinigle
 *
 */
public class RandomForest {
  ExtendedRandom ex_;
  RandomTree rt_;
  public RandomForest(ExtendedRandom ex) {
    ex_ = ex;
    rt_ = new RandomTree(ex);
  }
  
  /**
   * Creates a random forest.
   * nodes * trees
   * 
   * @param nodes number of nodes
   * @param trees number of trees
   * @return
   */
  public int[] RandomForestGen(int nodes, int trees) {
    assert nodes >= 1 && trees >= 1 && trees <= nodes;
    int[] bagian = new int[nodes];
    for (int i = 0; i < nodes; ++i) {
      if (i < trees) bagian[i] = i; else bagian[i] = ex_.nextInt(trees);
    }
    
    ex_.nextShuffle(bagian);
    
    int[] parent = new int[nodes];
    for (int i = 0; i < trees; ++i) {
      ArrayList<Integer> nod = new ArrayList<Integer>();
      
      // TODO(irvan): make this more efficient
      for (int j = 0; j < nodes; ++j) if (bagian[j] == i) nod.add(j);
      
      int[] minp = rt_.RandomDirectedTree(nod.size());
      Integer[] perm = new Integer[nod.size()];
      nod.toArray(perm);
      
      ex_.nextShuffle(perm);
      
      for (int j = 0; j < minp.length; ++j) {
        if (minp[j] == -1) {
          parent[perm[j]] = -1;
        } else {
          parent[perm[j]] = perm[minp[j]];
        }
      }
    }
    
    return parent;
  }
}
